#include "net/tcp_stream.h"
#include "net/socket.h"
#include "net/buffer.h"
#include "net/processor.h"
#include "net/socket_opt.h"
#include "net/tcp_server.h"

namespace net {
TcpStream::TcpStream(Socket* sock, Poller* poller)
    : poller_(poller), sock_(sock), write_complete_closure_(NULL), processor_(
        NULL), close_closure_(NULL) {
}

TcpStream::~TcpStream() {
  poller_->Del(&ev_, EV_READ);
}

bool TcpStream::Init() {
  ev_.fd = sock_->Fd();
  ev_.arg = this;
  ev_.cb = HandleEvent;

  return poller_->Add(&ev_, EV_READ);
}

void TcpStream::HandleEvent(int fd, void* arg, int event) {
  TcpStream* stream = (TcpStream*) arg;
  switch (event) {
    case EV_READ:
      stream->HandleRead();
      break;
    case EV_WRITE:
      stream->HandleWrite();
      break;
    default:
      LOG(WARNING)<< "unknown event: " << event;
      break;
    }
  }

void TcpStream::HandleRead() {
  int32 ret = input_buf_->ReadFd(sock_->Fd());
  if (ret == -1) {
    return;
  } else if (ret == 0) {
    HandleClose();
    return;
  }

  processor_->HandleRead(this, input_buf_.get());
}

void TcpStream::HandleWrite() {
  AutoRun r(write_complete_closure_);
  write_complete_closure_ = NULL;

  size_t size = output_buf_->ReadableSize();
  int32 ret = sock::Send(sock_.get(), output_buf_.get());
  if (size != ret) {
    write_complete_closure_ = r.release();
    return;
  }

  poller_->Mod(&ev_, EV_READ);
}

void TcpStream::HandleClose() {
  poller_->Del(&ev_, EV_READ | EV_WRITE);

  AutoRun r(close_closure_.get());
}

int32 TcpStream::Fd() {
  return sock_->Fd();
}

void TcpStream::Send(const u_char* buf, size_t len, Closure* closure) {
  AutoRun r(closure);
  int32 ret = sock::Send(sock_.get(), buf, len);
  if (ret == len) return;

  // FIXME: Check whether sock closed...
  write_complete_closure_ = r.release();
  output_buf_->Append(buf, len);
  poller_->Mod(&ev_, EV_READ | EV_WRITE);
}

}
